using System.Diagnostics;
using MonoMod.Utils;
using RSCore;
using Terraria.GameContent;
using Terraria.GameInput;

namespace _ReplaceString_.UI.Styles;
public record UILayout() : UIStyle(false, true)
{
	public static UILayout Vertical { get; } = new VerticalLayout();
	public static UILayout Horizontal { get; } = new HorizontalLayout();
}

/// <summary>
/// 垂直布局
/// </summary>
file record VerticalLayout : UILayout
{
	public override void Apply(UIBase ui)
	{
		ui.OnRecalculate += Recalculate;
	}

	private bool Recalculate(UIBase ui)
	{
		float height = ui._innerDimensions.Height;
		int count = ui.Elements.Count;
		foreach (var child in ui.Elements)
		{
			Debug.Assert(child.Height.Precent == 0);
			if (child is UIBase myUI && myUI.Tag.Has(UITag.FixedHeight))
			{
				height -= child._outerDimensions.Height;
				count--;
			}
		}

		float childHeight = 0;
		if (height > 0 && count > 0)
		{
			childHeight = height / count;
		}
		float top = 0;
		foreach (var child in ui.Elements)
		{
			child.Top = new(top, 0);
			if (child is not UIBase myUI || !myUI.Tag.Has(UITag.FixedHeight))
			{
				var h = childHeight - child.MarginTop - child.MarginBottom;
				if (child.Height.Pixels != h)
				{
					child.Height = new(h, 0);
					child.Recalculate();
				}
			}
			top += child._outerDimensions.Height;
		}

		float totalHeight = top + ui.PaddingTop + ui.PaddingBottom;
		if (ui.Tag.Has(UITag.FlexibleHeight) && ui.Height.Pixels != totalHeight)
		{
			Debug.Assert(ui.Height.Precent == 0);
			ui.Height.Pixels = totalHeight;
			ui.Recalculate();
		}
		return true;
	}
}

/// <summary>
/// 水平布局
/// </summary>
file record HorizontalLayout : UILayout
{
	public override void Apply(UIBase ui)
	{
		ui.OnRecalculate += Recalculate;
	}

	private bool Recalculate(UIBase ui)
	{
		float width = ui._innerDimensions.Width;
		int count = ui.Elements.Count;
		foreach (var child in ui.Elements)
		{
			Debug.Assert(child.Width.Precent == 0);
			if (child is UIBase myUI && myUI.Tag.Has(UITag.FixedWidth))
			{
				width -= child._outerDimensions.Width;
				count--;
			}
		}

		float childWidth = 0;
		if (width > 0 && count > 0)
		{
			childWidth = width / count;
		}
		float left = 0;
		foreach (var child in ui.Elements)
		{
			child.Left = new(left, 0);
			if (child is not UIBase myUI || !myUI.Tag.Has(UITag.FixedWidth))
			{
				float w = childWidth - child.MarginLeft - child.MarginRight;
				if (child.Width.Pixels != w)
				{
					child.Width = new(w, 0);
					child.Recalculate();
				}
			}
			left += child._outerDimensions.Width;
		}

		float totalWidth = left + ui.PaddingLeft + ui.PaddingRight;
		if (ui.Tag.Has(UITag.FlexibleWidth) && ui.Width.Pixels != totalWidth)
		{
			Debug.Assert(ui.Width.Precent == 0);
			ui.Width.Pixels = totalWidth;
			ui.Recalculate();
		}
		return true;
	}
}
